package com.ruoyi.project.wechat.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.constant.WxOpenConstants;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.framework.config.properties.WxOpenPcLoginConfig;
import com.ruoyi.framework.redis.RedisCache;
import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.wechat.domain.WxOpenLoginConfig;
import com.ruoyi.project.wechat.mapper.WxOpenLoginConfigMapper;
import com.ruoyi.project.wechat.service.WxOpenLoginConfigService;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.http.URIUtil;
import me.chanjar.weixin.open.api.WxOpenComponentService;
import me.chanjar.weixin.open.api.WxOpenConfigStorage;
import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class WxOpenLoginConfigServiceImpl implements WxOpenLoginConfigService {

    private static final Logger logger = LoggerFactory.getLogger(WxOpenLoginConfigServiceImpl.class);

    @Resource
    private WxOpenLoginConfigMapper wxOpenLoginConfigMapper;

    @Resource
    private WxOpenPcLoginConfig wxOpenPcLoginConfig;

    @Resource
    private WxOpenConfigStorage wxOpenConfigStorage;

    @Resource
    private RedisCache redisCache;

    @Resource
    private WxOpenComponentService wxOpenComponentService;

    @Override
    public int deleteByPrimaryKey(Integer id) {
        return wxOpenLoginConfigMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int insert(WxOpenLoginConfig record) {
        return wxOpenLoginConfigMapper.insert(record);
    }

    @Override
    public int insertSelective(WxOpenLoginConfig record) {
        return wxOpenLoginConfigMapper.insertSelective(record);
    }

    @Override
    public WxOpenLoginConfig selectByPrimaryKey(Integer id) {
        return wxOpenLoginConfigMapper.selectByPrimaryKey(id);
    }

    @Override
    public WxOpenLoginConfig selectByAppId(String appId) {
        return wxOpenLoginConfigMapper.selectByAppId(appId);
    }

    @Override
    public int updateByPrimaryKeySelective(WxOpenLoginConfig record) {
        return wxOpenLoginConfigMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByPrimaryKey(WxOpenLoginConfig record) {
        return wxOpenLoginConfigMapper.updateByPrimaryKey(record);
    }

    @Override
    public String getWxLoginImage() {
        WxOpenLoginConfig wxOpenLoginConfig = wxOpenLoginConfigMapper.selectByAppId(wxOpenPcLoginConfig.getOpenPcAppId());
        StringBuffer sb = new StringBuffer(wxOpenPcLoginConfig.getLoginImgUrl());
        sb.append("?appid="+wxOpenLoginConfig.getAppId());
        sb.append("&redirect_uri="+ URIUtil.encodeURIComponent(wxOpenLoginConfig.getRedirectUri()));
        sb.append("&response_type="+wxOpenLoginConfig.getResponseType());
        sb.append("&scope="+wxOpenLoginConfig.getScope());
        sb.append("&state="+wxOpenLoginConfig.getState());
        return sb.toString();
    }

    @Override
    public AjaxResult getWxAccessToken(String code) {

        if (StringUtils.isEmpty(code)) {
            return AjaxResult.error("code is null");
        }
        //判断是否是管理员角色 不是管理员角色不能提交
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if(null == loginUser){
            return AjaxResult.error("请登录再操作");
        }
        Set<String> permissions = loginUser.getPermissions();
        boolean contains = permissions.contains("1");
        if(!contains){
            return AjaxResult.error("权限不足");
        }

        WxOpenLoginConfig wxOpenLoginConfig = wxOpenLoginConfigMapper.selectByAppId(wxOpenPcLoginConfig.getOpenPcAppId());
        StringBuffer sb = new StringBuffer();
        sb.append("appid="+wxOpenLoginConfig.getAppId());
        sb.append("&secret="+wxOpenLoginConfig.getAppSecret());
        sb.append("&code="+code);
        sb.append("&grant_type=authorization_code");
        String sendPost = HttpUtils.sendPost(wxOpenPcLoginConfig.getLoginOauth2Url(), sb.toString());
        JSONObject object = JSONObject.parseObject(sendPost);
        if(StringUtils.isEmpty(object.getString("unionid"))){
            return AjaxResult.error("登录code过期，请重新操作");
        }
        return AjaxResult.success(object);
    }

    @Override
    public String getAuthorizerToken(String appId) throws WxErrorException {

        String authorizerAccessToken = wxOpenConfigStorage.getAuthorizerAccessToken(appId);
        logger.info("获取redis中的authorizerAccessToken"+ authorizerAccessToken);
        if(StringUtils.isEmpty(authorizerAccessToken)){
            getAuthorizerRefreshToken(appId);
            authorizerAccessToken = wxOpenComponentService.getAuthorizerAccessToken(appId, false);
            wxOpenConfigStorage.updateAuthorizerAccessToken(appId,authorizerAccessToken,7200);
        }

        return authorizerAccessToken;
    }

    @Override
    public String getAuthorizerRefreshToken(String appId) throws WxErrorException {
        String authorizerRefreshToken = wxOpenConfigStorage.getAuthorizerRefreshToken(appId);
        if(StringUtils.isEmpty(authorizerRefreshToken)){
            WxOpenAuthorizerInfoResult authorizerInfo = wxOpenComponentService.getAuthorizerInfo(appId);
            authorizerRefreshToken = authorizerInfo.getAuthorizationInfo().getAuthorizerRefreshToken();
            if(!StringUtils.isEmpty(authorizerRefreshToken)){
                wxOpenConfigStorage.setAuthorizerRefreshToken(appId,authorizerRefreshToken);
            }
            logger.info("获取到的用户信息：{}", JSON.toJSONString(authorizerInfo));
        }
        return authorizerRefreshToken;
    }


}


